# coding=utf-8
from django.utils import timezone
import logging
import time
import traceback

from django.http import HttpResponseRedirect
from django.conf import settings
from django.http import HttpResponse
from django.contrib.auth.models import User
from django.contrib.sessions.models import Session
from django.utils.deprecation import MiddlewareMixin
from libs.utils.com_func import request_interrupt
import datetime
try:
    from django.utils.deprecation import MiddlewareMixin  # Django 1.10.x
except ImportError:
    MiddlewareMixin = object  # Django 1.4.x - Django 1.9.x

from libs.utils.ajax import ajax_fail
nologin_urls = []
SESSION_KEY = '_auth_user_id'
log = logging.getLogger(__name__)

exclude_urls = ["/site_media/", "/upload_media/"]
nologin_urls = ["/apidoc/", "/admin/login/", "/admin/management/login/", "/admin/regist/", "/admin/teachPlan/export/teach/plan/"]
#  "/admin/teachPlan/", '/admin/dataDetail/', '/admin/user/list' "/admin/regist/",
# "/admin/search/", "/admin/detection/", "/admin/than/"

class AuthenticationMiddleware(MiddlewareMixin):
    """"""
    @request_interrupt
    def process_request(self, request):
        """
        """
        if request.method == 'OPTIONS':
            return HttpResponse()
        path = str(request.path)
        # if not path.startswith('/stu/account/heartbeat/') and not path.startswith('/tea/test/supervise/stu/list/') and \
        #         not path.startswith('/tea/heartbeat/'):
        #     print request.get_full_path()
        if path.startswith('/site_media/') or path.startswith('/upload_media/') or path.startswith('/apidoc/') \
                or next((x for x in [path.startswith(obj) for obj in nologin_urls] if x), False):
            pass
        else:
            uid = 0
            session_key = ""
            print(request.get_full_path())
            # print(request.GET.get("sessionid"),'=====dsdsdsd')
            if request.META.get("HTTP_SESSIONID"):
                session_key = request.META.get("HTTP_SESSIONID")
            if not session_key:
                if request.META.get("HTTP_SESSIONID"):
                    session_key = request.META.get("HTTP_SESSIONID")
            if session_key:
                try:
                    s = Session.objects.get(pk=session_key, expire_date__gt=datetime.datetime.now())
                    uid = s.get_decoded().get('_auth_user_id')
                except:
                    pass
            else:
                uid = request.GET.get("user_id") or 0

            request.uid = uid
            if not uid:
                # HttpResponseRedirect('/admin/index/')
                return ajax_fail(error=9, message=u"会话过期，请重新登录！")
            try:
                request.user = User.objects.get(pk=uid)
            except:
                request.user = None

        return None

    def process_view(self, request, view_func, view_args, view_kwargs):
        """
                """
        # if not settings.DEBUG:
        #     return None

        path = str(request.path)
        # 如果请求的路径为 js css 文件 不处理
        if path.startswith('/site_media/'):
            return None
        if path.startswith('/media/'):
            return None
        # 如果请求的路径为 js css 文件 不处理
        if path.startswith('/theme_media/'):
            return None
        # 如果请求的路径为 js css 文件 不处理
        if path.startswith('/upload_media/'):
            return None
        # get number of db queries before we do anything

        # try:
        #     uid = request.uid
        # except:
        #     uid = 0

        # time the view
        start = time.time()

        # response = view_func(request, *view_args, **view_kwargs)

        if settings.DEBUG:
            try:
                response = view_func(request, *view_args, **view_kwargs)
            except Exception as e:
                traceback.print_exc()

                return ajax_fail(error='', message=settings.ERROR_MESSAGES)
        else:
            try:
                response = view_func(request, *view_args, **view_kwargs)

            except Exception as e:

                traceback.print_exc()

                return ajax_fail(error='', message=settings.ERROR_MESSAGES)

        totTime = time.time() - start

        response['query_time'] = int(totTime * 1000)

        return response

    def process_response(self, request, response):
        try:
            path = str(request.path)
            if path not in exclude_urls:
                pass
            response["Access-Control-Allow-Origin"] = "*"
            response["Access-Control-Allow-Methods"] = "POST, GET, OPTIONS"
            response["Access-Control-Allow-Headers"] = "Origin, X-Requested-With, Content-Type, Accept, sessionid"
            response["Access-Control-Max-Age"] = "1728000"
            response["Access-Control-Expose-Headers"] = 'Date'  # 允许前端获取响应头里面的date字段 保持与服务器时间统一
        except Exception as e:
            log.debug("process_response1:%s" % e)
        return response

    def process_exception(self, request, exception):
        """
        功能说明:view函数抛出异常处理
        -------------------------------
        修改人     修改时间
        --------------------------------
        徐威      2013-07-17
        """
        path = str(request.path)

        # 如果请求的路径为 js css 文件 不处理
        if path.startswith('/site_media/'):
            return None
        if path.startswith('/media/'):
            return None
        # 如果请求的路径为 js css 文件 不处理
        if path.startswith('/theme_media/'):
            return None
        # 如果请求的路径为 js css 文件 不处理
        if path.startswith('/upload_media/'):
            return None
        log.error("process_exception:%s" % exception)
        log.error(traceback.format_exc(), request=request)

        if request.method == "POST":
            return ajax_fail(error="500", message=u"服务器开小差了~~")
        return ajax_fail(error="500", message=u"服务器开小差了~~")
